package com.atguigu.gulimall.product.service.impl;

import com.atguigu.gulimall.product.service.CategoryBrandRelationService;
import com.atguigu.gulimall.product.vo.Catelog2Vo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    CategoryBrandRelationService categoryBrandRelationService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listTree() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
        List<CategoryEntity> level1Menu = categoryEntities.stream()
                .filter(e -> e.getParentCid() == 0)
                .map(entity->{
                    entity.setChildren(getChildren(entity,categoryEntities));
                    return entity;
                })
                .sorted((e1,e2)-> (e1.getSort()==null?0:e1.getSort())-(e2.getSort()==null?0:e2.getSort()))
                .collect(Collectors.toList());
        return level1Menu;
    }

    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        if(!StringUtils.isEmpty(category.getName())){
            categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
        }
    }

    @Override
    public void removeMenuByIds(List<Long> asList) {
        baseMapper.deleteBatchIds(asList);//因为baseMapper是CategoryDao的实例，所以由它调的都是操作的
    }

    public List<CategoryEntity> getChildren(CategoryEntity categoryEntity,List<CategoryEntity> list){
        List<CategoryEntity> level1Menu=list.stream()
                .filter(e->e.getParentCid()==categoryEntity.getCatId())
                .map(entity->{
                    entity.setChildren(getChildren(entity,list));
                    return entity;
                })
                .sorted((e1,e2)-> (e1.getSort()==null?0:e1.getSort())-(e2.getSort()==null?0:e2.getSort()))
                .collect(Collectors.toList());
        return level1Menu;
    }

    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> path=new ArrayList<>();
        List<Long> parentPath = findParentPath(catelogId, path);
        Collections.reverse(parentPath);
        return parentPath.toArray(new Long[parentPath.size()]);
    }

    /**
     * 从已有的list里查出parent_cid==parentCid的所有
     * @param categoryEntities
     * @param parentCid
     * @return
     */
    @Override
    public List<CategoryEntity> getFromParentCid(List<CategoryEntity> categoryEntities,Long parentCid){
        List<CategoryEntity> collect = categoryEntities.stream().filter((item) -> {
            return item.getParentCid() == parentCid;
        }).collect(Collectors.toList());
        return collect;
    }


    @Override
    public Map<String,  List<Catelog2Vo>> getCatalogJson() {
//        获得所有数据，接下来对数据的操作都是基于这些数据进行封装，不用做额外的db操作
        List<CategoryEntity> collect = this.list(new QueryWrapper<>());
//        1、一级分类
        List<CategoryEntity> level1Categories = getFromParentCid(collect,0L);
        Map<String, List<Catelog2Vo>> map = level1Categories.stream().collect(Collectors.toMap(k->k.getCatId().toString(), v -> {
//        2、二级分类
            List<CategoryEntity> level2Categories = getFromParentCid(collect,v.getCatId());
            List<Catelog2Vo> catelog2VoList = level2Categories.stream().map((l2) -> {
                List<CategoryEntity> level3Categories = getFromParentCid(collect,l2.getCatId());
//                获得catelog3VoList
                List<Catelog2Vo.Catelog3Vo> catelog3VoList = level3Categories.stream().map((l3) -> {
                    return new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
                }).collect(Collectors.toList());
                Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), catelog3VoList, l2.getCatId().toString(), l2.getName());
                return catelog2Vo;
            }).collect(Collectors.toList());
            return catelog2VoList;
        }));
        return map;
    }

    @Override
    public List<CategoryEntity> cagetLevel1Categorys() {
        return this.list(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0L));
    }

    public List<Long> findParentPath(Long catelogId,List<Long> path){
        path.add(catelogId);
        CategoryEntity categoryEntity = this.getById(catelogId);
        if( categoryEntity.getParentCid() != 0){
            findParentPath(categoryEntity.getParentCid(),path);
        }
        return path;
    }

}